package com.wang.tool.serialize;

import com.caucho.hessian.io.HessianInput;
import com.caucho.hessian.io.HessianOutput;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.Base64;

/**
 * @see Serializable
 * suggestion use fixed serialVersionUID
 * eg :private static final long serialVersionUID = 1L;
 */
public class HessianSerializationUtil {


    /**
     * @param obj
     * @return
     * @throws SerializationException
     * @see HessianSerializationUtil#deserialize(byte[])
     */
    public static byte[] serialize(Serializable obj) throws SerializationException {
        if (obj == null) {
            return new byte[]{};
        }
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            HessianOutput ho = new HessianOutput(bos);
            ho.writeObject(obj);
            return bos.toByteArray();
        } catch (Throwable e) {
            throw new SerializationException(e, SerializationException.SERIALIZE_ERROR, e.getMessage());
        }
    }

    /**
     * @param source
     * @param <T>
     * @return
     * @throws SerializationException
     * @see HessianSerializationUtil#serialize(Serializable)
     */
    public static <T extends Serializable> T deserialize(byte[] source) throws SerializationException {
        if (source == null || source.length == 0) {
            return null;
        }
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(source);
            HessianInput hi = new HessianInput(bis);
            return (T) hi.readObject();
        } catch (IOException e) {
            throw new SerializationException(e, SerializationException.DESERIALIZE_ERROR, e.getMessage());
        }
    }

    /**
     * @param obj
     * @return
     * @throws SerializationException
     * @see HessianSerializationUtil#serializeToStr(Serializable)
     */
    public static String serializeToStr(Serializable obj) throws SerializationException {
        byte[] serializedData = serialize(obj);
        if (serializedData.length == 0) {
            return null;
        }
        return Base64.getEncoder().encodeToString(serializedData);
    }

    /**
     * @param str
     * @param <T>
     * @return
     * @throws SerializationException
     * @see HessianSerializationUtil#deserializeFromStr(String)
     */
    public static <T extends Serializable> T deserializeFromStr(String str) throws SerializationException {
        if (str == null || str.isEmpty()) {
            return null;
        }
        byte[] data = Base64.getDecoder().decode(str);
        return deserialize(data);
    }

}